package com.baoyz.swipemenulistview;

import android.content.Context;
import androidx.core.view.MotionEventCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.widget.ListAdapter;
import android.widget.ListView;

/**
 * @author baoyz
 * @date 2014-8-18
 */
public class SwipeMenuListView extends ListView {

    private static final int TOUCH_STATE_NONE = 0;
    private static final int TOUCH_STATE_X = 1;
    private static final int TOUCH_STATE_Y = 2;

    public static final int DIRECTION_LEFT = 1;
    public static final int DIRECTION_RIGHT = -1;
    protected int mDirection = 1;//swipe from right to left by default

    private int MAX_Y = 5;
    private int MAX_X = 3;
    private float mDownX;
    private float mDownY;
    private int mTouchState;
    private int mTouchPosition;
    private SwipeMenuLayout mTouchView;
    private OnSwipeListener mOnSwipeListener;

    private SwipeMenuCreator mMenuCreator;
    private OnMenuItemClickListener mOnMenuItemClickListener;
    protected OnMenuStateChangeListener mOnMenuStateChangeListener;
    private Interpolator mCloseInterpolator;
    private Interpolator mOpenInterpolator;
    private boolean need = false;

    public SwipeMenuListView(Context context) {
        super(context);
        init();
    }

    public SwipeMenuListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public SwipeMenuListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        MAX_X = dp2px(MAX_X);
        MAX_Y = dp2px(MAX_Y);
        mTouchState = TOUCH_STATE_NONE;
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(new SwipeMenuAdapter(getContext(), adapter) {
            @Override
            public void createMenu(SwipeMenu menu) {
                if (mMenuCreator != null) {
                    mMenuCreator.create(menu);
                }
            }

            @Override
            public void onItemClick(SwipeMenuView view, SwipeMenu menu,
                                    int index) {
                boolean flag = false;
                if (mOnMenuItemClickListener != null) {
                    flag = mOnMenuItemClickListener.onMenuItemClick(
                            view.getPosition(), menu, index);
                }
                if (mTouchView != null && !flag) {
                    mTouchView.smoothCloseMenu();
                }
            }
        });
    }

    public void setCloseInterpolator(Interpolator interpolator) {
        mCloseInterpolator = interpolator;
    }

    public void setOpenInterpolator(Interpolator interpolator) {
        mOpenInterpolator = interpolator;
    }

    public Interpolator getOpenInterpolator() {
        return mOpenInterpolator;
    }

    public Interpolator getCloseInterpolator() {
        return mCloseInterpolator;
    }

    /**
     *  设置为true 可以解决滑动冲突 yqs 2017.2.24
     * @param need
     */
    public void setIsNeedIntercept(boolean need) {
        this.need = need;
    }

    //    @Override
//    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        //在拦截处处理，在滑动设置了点击事件的地方也能swip，点击时又不能影响原来的点击事件
//        int action = ev.getAction();
//        switch (action) {
//            case MotionEvent.ACTION_DOWN:
//                //-----------hu-2017-1-22-------------------------
//                if (ev.getX() < TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,20,getResources().getDisplayMetrics())){
//                    return false;
//                }else {
//                    this.getParent().requestDisallowInterceptTouchEvent(true);//yqs 2017/1/22 滑动冲突
//                }
//                //-----------hu-2017-1-22-------------------------
//                mDownX = ev.getX();
//                mDownY = ev.getY();
//                boolean handled = super.onInterceptTouchEvent(ev);
//                mTouchState = TOUCH_STATE_NONE;
//                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
//                View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
//
//                //只在空的时候赋值 以免每次触摸都赋值，会有多个open状态
//                if (view instanceof SwipeMenuLayout) {
//                    //如果有打开了 就拦截.
//                    if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) {
//                        return true;
//                    }
//                    mTouchView = (SwipeMenuLayout) view;
//                    mTouchView.setSwipeDirection(mDirection);
//                }
//                //如果摸在另外个view
//                if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) {
//                    handled = true;
//                }
//
//                if (mTouchView != null) {
//                    mTouchView.onSwipe(ev);
//                }
//                return handled;
//            case MotionEvent.ACTION_MOVE:
//                float dy = Math.abs((ev.getY() - mDownY));
//                float dx = Math.abs((ev.getX() - mDownX));
//                if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) {
//                    //每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了
//                    if (mTouchState == TOUCH_STATE_NONE) {
//                        if (Math.abs(dy) > MAX_Y) {
//                            mTouchState = TOUCH_STATE_Y;
//                        } else if (dx > MAX_X) {
//                            mTouchState = TOUCH_STATE_X;
//                            if (mOnSwipeListener != null) {
//                                mOnSwipeListener.onSwipeStart(mTouchPosition);
//                            }
//                        }
//                    }
//                    return true;
//                }
//                break;
//            //-----------hu-2017-1-22-------------------------
//            case MotionEvent.ACTION_UP:
//            default:
//                this.getParent().requestDisallowInterceptTouchEvent(false);//yqs 2017/1/22 滑动冲突
//                break;
//            //-----------hu-2017-1-22-------------------------
//        }
//        return super.onInterceptTouchEvent(ev);
//    }
//
//    @Override
//    public boolean onTouchEvent(MotionEvent ev) {
//        if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)
//            return super.onTouchEvent(ev);
//        int action = ev.getAction();
//        switch (action) {
//            case MotionEvent.ACTION_DOWN:
//                int oldPos = mTouchPosition;
//                mDownX = ev.getX();
//                mDownY = ev.getY();
//                mTouchState = TOUCH_STATE_NONE;
//
//                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
//                View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
//                /********新添加的内容,当按下的item不是当前已经打开的item,则关闭已经打开的item,并返回false.不再响应down以后的事件,仿qq效果********/
//                if (view !=null && mTouchView != null && view instanceof SwipeMenuLayout) {
//                    SwipeMenuLayout touchView = (SwipeMenuLayout) view;
//                    if (!touchView.isOpen() && mTouchView.isOpen()) {
//                        mTouchView.smoothCloseMenu();
//                    }
//                }
//                /***************************/
//                if (mTouchPosition == oldPos && mTouchView != null
//                        && mTouchView.isOpen()) {
//
//                    mTouchState = TOUCH_STATE_X;
//                    mTouchView.onSwipe(ev);
//                    return true;
//                }
//
//                if (mTouchView != null && mTouchView.isOpen()) {
//                    mTouchView.smoothCloseMenu();
//                    mTouchView = null;
//                    // return super.onTouchEvent(ev);
//                    // try to cancel the touch event
//                    MotionEvent cancelEvent = MotionEvent.obtain(ev);
//                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
//                    onTouchEvent(cancelEvent);
//                    if (mOnMenuStateChangeListener != null) {
//                        mOnMenuStateChangeListener.onMenuClose(oldPos);
//                    }
//                    return true;
//                }
//                if (view instanceof SwipeMenuLayout) {
//                    mTouchView = (SwipeMenuLayout) view;
//                    mTouchView.setSwipeDirection(mDirection);
//                }
//                if (mTouchView != null) {
//                    mTouchView.onSwipe(ev);
//                }
//                break;
//            case MotionEvent.ACTION_MOVE:
//                //有些可能有header,要减去header再判断
//                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()) - getHeaderViewsCount();
//                //如果滑动了一下没完全展现，就收回去，这时候mTouchView已经赋值，再滑动另外一个不可以swip的view
//                //会导致mTouchView swip 。 所以要用位置判断是否滑动的是一个view
//                if (!mTouchView.getSwipEnable() || mTouchPosition != mTouchView.getPosition()) {
//                    break;
//                }
//                float dy = Math.abs((ev.getY() - mDownY));
//                float dx = Math.abs((ev.getX() - mDownX));
//                if (mTouchState == TOUCH_STATE_X) {
//                    if (mTouchView != null) {
//                        mTouchView.onSwipe(ev);
//                    }
//                    getSelector().setState(new int[]{0});
//                    ev.setAction(MotionEvent.ACTION_CANCEL);
//                    super.onTouchEvent(ev);
//                    return true;
//                } else if (mTouchState == TOUCH_STATE_NONE) {
//                    if (Math.abs(dy) > MAX_Y) {
//                        mTouchState = TOUCH_STATE_Y;
//                    } else if (dx > MAX_X) {
//                        mTouchState = TOUCH_STATE_X;
//                        if (mOnSwipeListener != null) {
//                            mOnSwipeListener.onSwipeStart(mTouchPosition);
//                        }
//                    }
//                }
//                break;
//            case MotionEvent.ACTION_UP:
//                if (mTouchState == TOUCH_STATE_X) {
//                    if (mTouchView != null) {
//                        boolean isBeforeOpen = mTouchView.isOpen();
//                        mTouchView.onSwipe(ev);
//                        boolean isAfterOpen = mTouchView.isOpen();
//                        if (isBeforeOpen != isAfterOpen && mOnMenuStateChangeListener != null) {
//                            if (isAfterOpen) {
//                                mOnMenuStateChangeListener.onMenuOpen(mTouchPosition);
//                            } else {
//                                mOnMenuStateChangeListener.onMenuClose(mTouchPosition);
//                            }
//                        }
//                        if (!isAfterOpen) {
//                            mTouchPosition = -1;
//                            mTouchView = null;
//                        }
//                    }
//                    if (mOnSwipeListener != null) {
//                        mOnSwipeListener.onSwipeEnd(mTouchPosition);
//                    }
//                    ev.setAction(MotionEvent.ACTION_CANCEL);
//                    super.onTouchEvent(ev);
//                    return true;
//                }
//                break;
//        }
//        return super.onTouchEvent(ev);
//    }


    public boolean onInterceptTouchEvent(MotionEvent ev) {
        WindowManager wm = (WindowManager) getContext()
                .getSystemService(Context.WINDOW_SERVICE);

        int width = wm.getDefaultDisplay().getWidth();



        if (need){
            //在拦截处处理，在滑动设置了点击事件的地方也能swip，点击时又不能影响原来的点击事件
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    mDownX = ev.getX();
                    mDownY = ev.getY();
                    boolean handled = super.onInterceptTouchEvent(ev);
                    mTouchState = TOUCH_STATE_NONE;
                    mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
                    View view = getChildAt(mTouchPosition - getFirstVisiblePosition());

                    if (ev.getX() < TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics())) {
                        return false;
                    } else if (ev.getX() < width * 3 / 4 && ev.getX() > TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics())) {

                        if (view instanceof SwipeMenuLayout && !((SwipeMenuLayout) view).isOpen()) {
                            if (mTouchView != null) {
                                mTouchView.setSwipEnable(true);
                            }
                            ((SwipeMenuLayout) view).setSwipEnable(false);
                            return false;
                        }
                    }
                    if (view instanceof SwipeMenuLayout) {
                        ((SwipeMenuLayout) view).setSwipEnable(true);
                    } else {
                        //空白区域
                        return false;
                    }
                    if (mTouchView != null) {
                        mTouchView.setSwipEnable(true);
                    }
                        this.getParent().requestDisallowInterceptTouchEvent(true);//yqs 2017/1/22 滑动冲突


                    //只在空的时候赋值 以免每次触摸都赋值，会有多个open状态
                    if (view instanceof SwipeMenuLayout) {

                        //如果有打开了 就拦截.
                        if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) {
                            return true;
                        }
                        mTouchView = (SwipeMenuLayout) view;
                        mTouchView.setSwipeDirection(mDirection);
                    }
                    //如果摸在另外个view
                    if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) {
                        handled = true;
                    }

                    if (mTouchView != null) {
                        mTouchView.onSwipe(ev);
                    }
                    return handled;
                case MotionEvent.ACTION_MOVE:
                    float dy = Math.abs((ev.getY() - mDownY));
                    float dx = Math.abs((ev.getX() - mDownX));
                    if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) {
                        //每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了
                        if (mTouchState == TOUCH_STATE_NONE) {
                            if (Math.abs(dy) > MAX_Y) {
                                mTouchState = TOUCH_STATE_Y;
                            } else if (dx > MAX_X) {
                                mTouchState = TOUCH_STATE_X;
                                if (mOnSwipeListener != null) {
                                    mOnSwipeListener.onSwipeStart(mTouchPosition);
                                }
                            }
                        }
                        return true;
                    }
                    break;
                //-----------hu-2017-1-22-------------------------
                case MotionEvent.ACTION_UP:
                default:

//                    if (view instanceof SwipeMenuLayout)
//                        ((SwipeMenuLayout) view).setSwipEnable(true);
//                    if (mTouchView != null) {
//                        mTouchView.setSwipEnable(true);
//                    }
                    this.getParent().requestDisallowInterceptTouchEvent(false);//yqs 2017/1/22 滑动冲突
                    break;
                //-----------hu-2017-1-22-------------------------
            }
            return super.onInterceptTouchEvent(ev);
        }else {
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    mDownX = ev.getX();
                    mDownY = ev.getY();
                    boolean handled = super.onInterceptTouchEvent(ev);
                    mTouchState = TOUCH_STATE_NONE;
                    mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
                    View view = getChildAt(mTouchPosition - getFirstVisiblePosition());

                    //只在空的时候赋值 以免每次触摸都赋值，会有多个open状态
                    if (view instanceof SwipeMenuLayout) {
                        //如果有打开了 就拦截.
                        if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) {
                            return true;
                        }
                        mTouchView = (SwipeMenuLayout) view;
                        mTouchView.setSwipeDirection(mDirection);
                    }
                    //如果摸在另外个view
                    if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) {
                        handled = true;
                    }

                    if (mTouchView != null) {
                        mTouchView.onSwipe(ev);
                    }
                    return handled;
                case MotionEvent.ACTION_MOVE:
                    float dy = Math.abs((ev.getY() - mDownY));
                    float dx = Math.abs((ev.getX() - mDownX));
                    if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) {
                        //每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了
                        if (mTouchState == TOUCH_STATE_NONE) {
                            if (Math.abs(dy) > MAX_Y) {
                                mTouchState = TOUCH_STATE_Y;
                            } else if (dx > MAX_X) {
                                mTouchState = TOUCH_STATE_X;
                                if (mOnSwipeListener != null) {
                                    mOnSwipeListener.onSwipeStart(mTouchPosition);
                                }
                            }
                        }
                        return true;
                    }
            }
            return super.onInterceptTouchEvent(ev);
        }

    }
    public boolean onTouchEvent(MotionEvent ev) {
        if (need) {
            if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)
                return super.onTouchEvent(ev);
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    int oldPos = mTouchPosition;
                    mDownX = ev.getX();
                    mDownY = ev.getY();
                    mTouchState = TOUCH_STATE_NONE;

                    mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
                    View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
                    /********新添加的内容,当按下的item不是当前已经打开的item,则关闭已经打开的item,并返回false.不再响应down以后的事件,仿qq效果********/
                    if (view != null && mTouchView != null && view instanceof SwipeMenuLayout) {
                        SwipeMenuLayout touchView = (SwipeMenuLayout) view;
                        if (!touchView.isOpen() && mTouchView.isOpen()) {
                            mTouchView.smoothCloseMenu();
                        }
                    }
                    /***************************/
                    if (mTouchPosition == oldPos && mTouchView != null
                            && mTouchView.isOpen()) {

                        mTouchState = TOUCH_STATE_X;
                        mTouchView.onSwipe(ev);
                        return true;
                    }

                    if (mTouchView != null && mTouchView.isOpen()) {
                        mTouchView.smoothCloseMenu();
                        mTouchView = null;
                        // return super.onTouchEvent(ev);
                        // try to cancel the touch event
                        MotionEvent cancelEvent = MotionEvent.obtain(ev);
                        cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
                        onTouchEvent(cancelEvent);
                        if (mOnMenuStateChangeListener != null) {
                            mOnMenuStateChangeListener.onMenuClose(oldPos);
                        }
                        return true;
                    }
                    if (view instanceof SwipeMenuLayout) {
                        mTouchView = (SwipeMenuLayout) view;
                        mTouchView.setSwipeDirection(mDirection);
                    }
                    if (mTouchView != null) {
                        mTouchView.onSwipe(ev);
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    //有些可能有header,要减去header再判断
                    mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()) - getHeaderViewsCount();
                    //如果滑动了一下没完全展现，就收回去，这时候mTouchView已经赋值，再滑动另外一个不可以swip的view
                    //会导致mTouchView swip 。 所以要用位置判断是否滑动的是一个view
                    if (!mTouchView.getSwipEnable() || mTouchPosition != mTouchView.getPosition()) {
                        break;
                    }
                    float dy = Math.abs((ev.getY() - mDownY));
                    float dx = Math.abs((ev.getX() - mDownX));
                    if (mTouchState == TOUCH_STATE_X) {
                        if (mTouchView != null) {
                            mTouchView.onSwipe(ev);
                        }
                        getSelector().setState(new int[]{0});
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        super.onTouchEvent(ev);
                        return true;
                    } else if (mTouchState == TOUCH_STATE_NONE) {
                        if (Math.abs(dy) > MAX_Y) {
                            mTouchState = TOUCH_STATE_Y;
                        } else if (dx > MAX_X) {
                            mTouchState = TOUCH_STATE_X;
                            if (mOnSwipeListener != null) {
                                mOnSwipeListener.onSwipeStart(mTouchPosition);
                            }
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    if (mTouchState == TOUCH_STATE_X) {
                        if (mTouchView != null) {
                            boolean isBeforeOpen = mTouchView.isOpen();
                            mTouchView.onSwipe(ev);
                            boolean isAfterOpen = mTouchView.isOpen();
                            if (isBeforeOpen != isAfterOpen && mOnMenuStateChangeListener != null) {
                                if (isAfterOpen) {
                                    mOnMenuStateChangeListener.onMenuOpen(mTouchPosition);
                                } else {
                                    mOnMenuStateChangeListener.onMenuClose(mTouchPosition);
                                }
                            }
                            if (!isAfterOpen) {
                                mTouchPosition = -1;
                                mTouchView = null;
                            }
                        }
                        if (mOnSwipeListener != null) {
                            mOnSwipeListener.onSwipeEnd(mTouchPosition);
                        }
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        super.onTouchEvent(ev);
                        return true;
                    }
                    break;
            }
            return super.onTouchEvent(ev);
        } else {
            if (ev.getAction() != 0 && this.mTouchView == null) {
                return super.onTouchEvent(ev);
            } else {
                int action = MotionEventCompat.getActionMasked(ev);
                action = ev.getAction();
                switch (action) {
                    case 0:
                        int oldPos = this.mTouchPosition;
                        this.mDownX = ev.getX();
                        this.mDownY = ev.getY();
                        this.mTouchState = 0;
                        this.mTouchPosition = this.pointToPosition((int) ev.getX(), (int) ev.getY());
                        if (this.mTouchPosition == oldPos && this.mTouchView != null && this.mTouchView.isOpen()) {
                            this.mTouchState = 1;
                            this.mTouchView.onSwipe(ev);
                            return true;
                        }

                        View view = this.getChildAt(this.mTouchPosition - this.getFirstVisiblePosition());
                        if (this.mTouchView != null && this.mTouchView.isOpen()) {
                            this.mTouchView.smoothCloseMenu();
                            this.mTouchView = null;
                            return super.onTouchEvent(ev);
                        }

                        if (view instanceof SwipeMenuLayout) {
                            this.mTouchView = (SwipeMenuLayout) view;
                        }

                        if (this.mTouchView != null) {
                            this.mTouchView.onSwipe(ev);
                        }
                        break;
                    case 1:
                        if (this.mTouchState == 1) {
                            if (this.mTouchView != null) {
                                this.mTouchView.onSwipe(ev);
                                if (!this.mTouchView.isOpen()) {
                                    this.mTouchPosition = -1;
                                    this.mTouchView = null;
                                }
                            }

                            if (this.mOnSwipeListener != null) {
                                this.mOnSwipeListener.onSwipeEnd(this.mTouchPosition);
                            }

                            ev.setAction(3);
                            super.onTouchEvent(ev);
                            return true;
                        }
                        break;
                    case 2:
                        float dy = Math.abs(ev.getY() - this.mDownY);
                        float dx = Math.abs(ev.getX() - this.mDownX);
                        if (this.mTouchState == 1) {
                            if (this.mTouchView != null) {
                                this.mTouchView.onSwipe(ev);
                            }

                            this.getSelector().setState(new int[1]);
                            ev.setAction(3);
                            super.onTouchEvent(ev);
                            return true;
                        }

                        if (this.mTouchState == 0) {
                            if (Math.abs(dy) > (float) this.MAX_Y) {
                                this.mTouchState = 2;
                            } else if (dx > (float) this.MAX_X) {
                                this.mTouchState = 1;
                                if (this.mOnSwipeListener != null) {
                                    this.mOnSwipeListener.onSwipeStart(this.mTouchPosition);
                                }
                            }
                        }
                }

                return super.onTouchEvent(ev);
            }
        }
    }

    public void smoothOpenMenu(int position) {
        if (position >= getFirstVisiblePosition()
                && position <= getLastVisiblePosition()) {
            View view = getChildAt(position - getFirstVisiblePosition());
            if (view instanceof SwipeMenuLayout) {
                mTouchPosition = position;
                if (mTouchView != null && mTouchView.isOpen()) {
                    mTouchView.smoothCloseMenu();
                }
                mTouchView = (SwipeMenuLayout) view;
                mTouchView.setSwipeDirection(mDirection);
                mTouchView.smoothOpenMenu();
            }
        }
    }

    public void smoothCloseMenu() {
        if (mTouchView != null && mTouchView.isOpen()) {
            mTouchView.smoothCloseMenu();
        }
    }

    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getContext().getResources().getDisplayMetrics());
    }

    public void setMenuCreator(SwipeMenuCreator menuCreator) {
        this.mMenuCreator = menuCreator;
    }

    public void setOnMenuItemClickListener(
            OnMenuItemClickListener onMenuItemClickListener) {
        this.mOnMenuItemClickListener = onMenuItemClickListener;
    }

    public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
        this.mOnSwipeListener = onSwipeListener;
    }

    public void setOnMenuStateChangeListener(OnMenuStateChangeListener onMenuStateChangeListener) {
        mOnMenuStateChangeListener = onMenuStateChangeListener;
    }

    public static interface OnMenuItemClickListener {
        boolean onMenuItemClick(int position, SwipeMenu menu, int index);
    }

    public static interface OnSwipeListener {
        void onSwipeStart(int position);

        void onSwipeEnd(int position);
    }

    public static interface OnMenuStateChangeListener {
        void onMenuOpen(int position);

        void onMenuClose(int position);
    }

    public void setSwipeDirection(int direction) {
        mDirection = direction;
    }

    /**
     * 判断点击事件是否在某个view内
     *
     * @param view
     * @param ev
     * @return
     */
    public static boolean inRangeOfView(View view, MotionEvent ev) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int x = location[0];
        int y = location[1];
        if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) {
            return false;
        }
        return true;
    }
}
